package com.aegean.CommercialHotelBookSystem.user.dao.Impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.catalina.User;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.aegean.CommercialHotelBookSystem.factory.HibernateSessionFactory;
import com.aegean.CommercialHotelBookSystem.factory.MyTools;
import com.aegean.CommercialHotelBookSystem.model.Book;
import com.aegean.CommercialHotelBookSystem.model.BookDetail;
import com.aegean.CommercialHotelBookSystem.model.Customer;
import com.aegean.CommercialHotelBookSystem.model.Hotel;
import com.aegean.CommercialHotelBookSystem.model.Person;
import com.aegean.CommercialHotelBookSystem.model.Room;
import com.aegean.CommercialHotelBookSystem.user.dao.IUserDao;

public class UserDaoImpl implements IUserDao {

	@Override
	public Customer updateObject(Customer one) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			if (one instanceof Customer) {
				session.update(one);
				tx.commit();
			}
			return one;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			closeSession();
		}
	}

	@Override
	public Session getSession() {
		return HibernateSessionFactory.getSession();
	}

	@Override
	public void closeSession() {
		HibernateSessionFactory.closeSession();
	}

	@Override
	public Customer saveObject(Object o) {
		Session session = null;
		Transaction tx = null;
		Customer one = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			if (o instanceof Customer) {
				one = (Customer) o;
				session.save(one);
				tx.commit();
			}
			return one;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			closeSession();
		}
	}

	@Override
	public Customer searchCustomer(String User_Name, String User_Pwd) {
		Session session = null;
		Transaction tx = null;
		Customer one = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			Query q = session
					.createQuery("from Customer where Person_Login=:name and Person_Password=:pwd");
			q.setString("name", User_Name);
			q.setString("pwd", User_Pwd);
			one = (Customer) q.uniqueResult();
			return one;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			closeSession();
		}
	}

	@Override
	public Customer updatePwd(Customer one) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			if (one instanceof Customer) {
				session.merge(one);
				tx.commit();
			}
			return one;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			closeSession();
		}
	}

	@Override
	public List<Book> searchBooks(Customer customer, String hotel_Name,
			String book_Date) {
		Session session = null;
		Transaction tx = null;
		List<Book> books = null;
		DetachedCriteria dcr = DetachedCriteria.forClass(Book.class);
		if (hotel_Name != null && hotel_Name.length() != 0) {
			dcr.createAlias("book_Hotel", "a");
			dcr.add(Restrictions.like("a.hotel_Name", "%" + hotel_Name + "%"));
		}
		if (book_Date != null && book_Date.length() != 0) {
			dcr.add(Restrictions.eq("book_Time", MyTools.toDate(book_Date)));
		}
		try {
			session = getSession();
			tx = session.beginTransaction();
			Criteria cr = dcr.getExecutableCriteria(session);
			cr.add(Restrictions.eq("book_Customer.person_Id",
					customer.getPerson_Id()));
			cr.addOrder(Order.desc("book_Time"));
			cr.setCacheable(true);
			books = (List<Book>) cr.list();
			for (Book book : books) {
				Hibernate.initialize(book.getBook_Hotel());
			}
			return books;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			closeSession();
		}
	}

	@Override
	public List<BookDetail> searchBookDetails(int book_Id) {
		Session session = null;
		Transaction tx = null;
		List<BookDetail> bookDetails = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			Criteria cr = session.createCriteria(BookDetail.class);
			cr.add(Restrictions.eq("bookDetail_Book.book_Id", book_Id));
			cr.setCacheable(true);
			bookDetails = (List<BookDetail>) cr.list();
			return bookDetails;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			closeSession();
		}
	}

	@Override
	public boolean serachUser(String User_Name) {
		Session session = null;
		Transaction tx = null;
		Person one;
		Query q;
		try {
			session = getSession();
			tx = session.beginTransaction();
			q = session.createQuery("from Person where person_Login=:name");
			q.setString("name", User_Name);
			one = (Person) q.uniqueResult();
			if (one == null) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return false;
		} finally {
			closeSession();
		}
	}

}
